/*
 * @Author: rock
 * @Date: 2025-03-28 09:48:28
 * @LastEditors: rock 
 * @LastEditTime: 2025-10-01 16:52:51
 * @FilePath: /Server/main/Server.cpp
 * @Description: Ctrl+Num1-> For Document; Ctrl+Num2-> For Function
 * 
 * Copyright (c) 2025 by rock, All Rights Reserved. 
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>


#include "head.h"
#include "pack.h"

int main()
{
    //1. 创建套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    if(fd == -1)
    {
        perror("socket申请失败\n");
        return -1;
    }

    int optval = 1;    
    // 关键设置：启用端口复用
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    
    //2.绑定IP地址和端口号
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(PORT_);
    saddr.sin_addr.s_addr = INADDR_ANY;
    int ret = bind(fd, (struct sockaddr*)&saddr, sizeof(saddr));

    if(ret == -1)
    {
        perror("bind\n");
        return -1;
    }

    //3.监听
    ret = listen(fd, 128);
    if(ret == -1)
    {
        perror("listen\n");
        return -1;
    }

    //4.阻塞等待客户端的连接
    struct sockaddr_in caddr;
    int addrlen = sizeof(caddr);
    printf("等待客户端连接...\n");
    int cfd = accept(fd, (struct sockaddr*)&caddr, (socklen_t*)&addrlen);
    if(cfd == -1)
    {
        perror("accept\n");
        return -1;
    }

    //5.成功建立连接， 打印客户端信息
    char ip[32];
    printf("客户端IP: %s, 端口: %d\n", 
        inet_ntop(AF_INET, &caddr.sin_addr.s_addr, ip, sizeof(ip)),
        ntohs(caddr.sin_port)
    );

    DataPack data;

    //通信
    while(1)
    {
        //接受数据
    	char buff[1024] = {0};

	    int len = recv(cfd, buff, sizeof(buff), 0);    
        
        unPack(buff, data);

	    printf("接收到的字符长度: %d\n", len);
        printf("接收端数据包的总长度: %d\n", data.lenPack);
        printf("接收端数据的长度: %d\n", data.msgLen);
        printf("接收端的数据头部: %x\n", buff[0]);
        printf("接收端的数据尾部: %x\n", buff[data.lenPack - 1]);

    	if(len>0)
	    {
            printf("Client say: %s\n", data.msg);     
            
		    //向客户端发送数据
		    send(cfd,buff, len, 0 );	

            memset(buff, 0, sizeof(buff));
    	}
	    else if(len == 0)
    	{
    		printf("客户端已经断开连接");
            break;
	    }
        else
        {
            perror("recv\n");
            break;
        }
    }

    //6. 通信执行完毕
    close(cfd);
    close(fd);
    

    return 0;
}
